﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using AfterlifeLib.Collision;
using AfterlifeLib.Levels;

namespace AfterlifeLib.Projectiles
{
    public class ProjectileDestroyedEventArgs : EventArgs
    {
        public string ParticleSettings { get; set; }
        public Vector2 Position { get; set; }

        public ProjectileDestroyedEventArgs(string particleSettings, Vector2 position)
        {
            ParticleSettings = particleSettings;
            Position = position;
        }
    }

    public class ProjectileManager
    {
        const int MAX_PROJECTILES = 1000;

        public event EventHandler<ProjectileDestroyedEventArgs> ProjectileDestroyedEvent;

        private World world;
        private Projectile[] projectiles;
        private Queue<Projectile> inactiveProjectiles;

        public int ActiveProjectiles
        {
            get { return projectiles.Length - inactiveProjectiles.Count; }
        }

        public int InactiveProjectiles
        {
            get { return inactiveProjectiles.Count; }
        }

        public ProjectileManager()
        {

        }

        public void Initialize(World world)
        {
            this.world = world;

            projectiles = new Projectile[MAX_PROJECTILES];
            inactiveProjectiles = new Queue<Projectile>(MAX_PROJECTILES);

            for (int i = 0; i < projectiles.Length; i++)
            {
                projectiles[i] = new Projectile();
                inactiveProjectiles.Enqueue(projectiles[i]);
            }

        }

        public void Update(GameTime gameTime, Level level)
        {
            float delta = (float)gameTime.ElapsedGameTime.TotalSeconds;

            foreach (Projectile p in projectiles)
            {
                if (p.active)
                {
                    p.Update(delta);

                    int tileX = (int)p.position.X / Level.TileDrawWidth;
                    int tileY = (int)p.position.Y / Level.TileDrawHeight;

                    //Wall collision
                    if (level.CollisionLayer.InCollisionTile(tileX, tileY))
                    {
                        p.active = false;

                        if (ProjectileDestroyedEvent != null)
                            ProjectileDestroyedEvent(this, new ProjectileDestroyedEventArgs(p.particleEffect, p.position));
                    }

                    //Entity collision
                    

                    if (!p.active)
                        inactiveProjectiles.Enqueue(p);
                }
            }
        }

        public void Draw(PrimitiveBatch primitiveBatch, Camera2D camera)
        {
            primitiveBatch.Begin(PrimitiveType.LineList);
            {
                foreach (Projectile p in projectiles)
                {
                    if (!p.active)
                        continue;

                    p.Draw(primitiveBatch, camera);
                }
            }
            primitiveBatch.End();
        }

        public void AddProjectile(Vector2 position, float angle, float speed)
        {
            if (inactiveProjectiles.Count > 0)
            {
                Projectile p = inactiveProjectiles.Dequeue();

                p.Initialize(position, angle, speed, "Dust");
            }
        }
    }
}
